from collections.abc import Container, Iterable, Iterator, Mapping
from datetime import timedelta
from typing import Any, Literal, TypeVar, overload

from ..core import Context

_T = TypeVar('_T')

class Devices:
    @classmethod
    def from_path(cls, context: Context, path: str | bytes) -> Device: ...
    @classmethod
    def from_sys_path(cls, context: Context, sys_path: str | bytes) -> Device: ...
    @classmethod
    def from_name(cls, context: Context, subsystem: str | bytes, sys_name: str | bytes) -> Device: ...
    @classmethod
    def from_device_number(cls, context: Context, typ: Literal['char', 'block'], number: int) -> Device: ...
    @classmethod
    def from_device_file(cls, context: Context, filename: str) -> Device: ...
    @classmethod
    def from_interface_index(cls, context: Context, ifindex: int) -> Device: ...
    @classmethod
    def from_kernel_device(cls, context: Context, kernel_device: str) -> Device: ...
    @classmethod
    def from_environment(cls, context: Context) -> Device: ...


class Device:
    def __del__(self) -> None: ...
    @property
    def parent(self) -> Device | None: ...
    @property
    def children(self) -> Iterator[Device]: ...
    @property
    def ancestors(self) -> Iterator[Device]: ...
    def find_parent(self, subsystem: str | bytes, device_type: str | bytes | None = None) -> Device | None: ...
    @property
    def sys_path(self) -> str: ...
    @property
    def device_path(self) -> str: ...
    @property
    def subsystem(self) -> str | None: ...
    @property
    def sys_name(self) -> str: ...
    @property
    def sys_number(self) -> str | None: ...
    @property
    def device_type(self) -> str | None: ...
    @property
    def driver(self) -> str | None: ...
    @property
    def device_node(self) -> str | None: ...
    @property
    def device_number(self) -> int: ...
    @property
    def is_initialized(self) -> bool: ...
    @property
    def time_since_initialized(self) -> timedelta: ...
    @property
    def device_links(self) -> Iterator[str]: ...
    @property
    def action(self) -> str | None: ...
    @property
    def sequence_number(self) -> int: ...
    @property
    def attributes(self) -> Attributes: ...
    @property
    def properties(self) -> Properties: ...
    @property
    def tags(self) -> Tags: ...
    def __hash__(self) -> int: ...
    def __eq__(self, other: object) -> bool: ...
    def __ne__(self, other: object) -> bool: ...
    def __gt__(self, other: object) -> bool: ...
    def __lt__(self, other: object) -> bool: ...
    def __le__(self, other: object) -> bool: ...
    def __ge__(self, other: object) -> bool: ...

class Properties(Mapping[str | bytes, str]):
    def __init__(self, device: Device) -> None: ...
    def asint(self, prop: str | bytes) -> int: ...
    def asbool(self, prop: str | bytes) -> bool: ...

class Attributes:
    def __init__(self, device: Device) -> None: ...
    @property
    def available_attributes(self) -> Iterator[str]: ...
    @overload
    def get(self, attribute: str, default: None = None) -> Any | None: ...
    @overload
    def get(self, attribute: str, default: _T) -> Any | _T: ...
    def asstring(self, attribute: str) -> str: ...
    def asint(self, attribute: str) -> int: ...
    def asbool(self, attribute: str) -> bool: ...

class Tags(Iterable[str], Container[str]):
    def __init__(self, device: Device) -> None: ...
    def __contains__(self, tag: object) -> bool: ...
    def __iter__(self) -> Iterator[str]: ...
